package com.gs.common.tool.utils;


import com.gs.common.tool.pojo.AnnotationInfo;
import com.gs.common.tool.pojo.ClassInfo;
import com.gs.common.tool.pojo.ColumnInfo;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类工具类
 * @author: guos
 * @date: 2025/03/12 16:11
 **/
public class ClzUtil {

    /**
     *换行
     */
    private static final String newline = "\n\n";


    /**
     * 生成java类
     * @param annotationList 类注解列表
     * @param isClz 是否是类
     * @param clzName 类全名
     * @param superClz 父类全名
     * @param inter 接口全名
     * @param clzComment 类注释
     * @param content 内容
     * @param thirdClzNameList 第三方类集合
     * @date 2025/03/12 16:24
     **/
    public static String genClass(List<AnnotationInfo> annotationList, boolean isClz, String clzName, ClassInfo superClz, ClassInfo inter, String clzComment, String authorName, String content, List<String> thirdClzNameList) {
        StringBuilder classInfo = new StringBuilder();
        classInfo.append(String.format("package %s;\n", PoJoUtil.getPackName(clzName)));
        if (Objects.nonNull(superClz)) {
            classInfo.append(String.format("\nimport %s;", superClz.getName()));
            if (CollectionUtil.isNotEmpty(superClz.getGenericList())) {
                superClz.getGenericList().forEach(s -> {
                    classInfo.append(String.format("\nimport %s;", s));
                });
            }
        }
        if (Objects.nonNull(inter)) {
            classInfo.append(String.format("\nimport %s;", inter.getName()));
            if (CollectionUtil.isNotEmpty(inter.getGenericList())) {
                superClz.getGenericList().forEach(s -> {
                    classInfo.append(String.format("\nimport %s;", s));
                });
            }
        }
        if (CollectionUtil.isNotEmpty(thirdClzNameList)) {
            thirdClzNameList.forEach(tcn -> classInfo.append(String.format("\nimport %s;", tcn)));
        }
        //换行
        classInfo.append(newline);
        //类注释
        classInfo.append(String.format("\n/**\n* %s\n* @author: %s\n* @date: %s\n**/", clzComment, authorName, DateUtil.formatDate(new Date(), DateUtil.yyyyMMddHHmmss3)));
        //类注解列表
        if (CollectionUtil.isNotEmpty(annotationList)) {
            classInfo.append(ClzUtil.addClzAnnotation(annotationList));
        }
        classInfo.append(String.format("\npublic %s %s", !isClz ? "interface" : "class", PoJoUtil.getShortName(clzName)));
        if (Objects.nonNull(superClz)) {
            if (CollectionUtil.isNotEmpty(superClz.getGenericList())) {
                String genericStr = superClz.getGenericList().stream().map(PoJoUtil::getShortName).collect(Collectors.joining(","));
                classInfo.append(String.format(" extends %s<%s>", PoJoUtil.getShortName(superClz.getName()), genericStr));
            } else {
                classInfo.append(String.format(" extends %s", PoJoUtil.getShortName(superClz.getName())));
            }
        }
        if (Objects.nonNull(inter)) {
            if (CollectionUtil.isNotEmpty(inter.getGenericList())) {
                String genericStr = inter.getGenericList().stream().map(PoJoUtil::getShortName).collect(Collectors.joining(","));
                classInfo.append(String.format(" implements %s<%s>", PoJoUtil.getShortName(inter.getName()), genericStr));
            } else {
                classInfo.append(String.format(" implements %s", PoJoUtil.getShortName(inter.getName())));
            }
        }
        classInfo.append(" {\n");
        if (StringUtil.isNotEmpty(content)) {
            classInfo.append(content);
        }
        classInfo.append("\n}");
        return classInfo.toString();
    }

    /**
     * 添加域
     * @param columnInfoList    列信息
     * @param thirdClzNameList  第三方类集合
     * @date 2025/03/12 18:39
     **/
    public static String addField(List<ColumnInfo> columnInfoList, List<String> thirdClzNameList) {
        if (CollectionUtil.isEmpty(columnInfoList)) {
            return "";
        }
        StringBuilder fieldInfo = new StringBuilder();
        //如果有多个主键，只给第一个加主键注解，其它加正常属性注解
        String pkCol = columnInfoList.stream().filter(ColumnInfo::isPK).map(ColumnInfo::getColumnName).findFirst().orElse(null);
        columnInfoList.stream().map(d -> d.getColumnName().equals(pkCol) ? d.setPK(true) : d.setPK(false)).forEach(c -> {
            fieldInfo.append(String.format("\n\n\t/**\n\t* %s\n\t*/", c.getColumnComment()));
            if (c.isPK()) {
                fieldInfo.append(String.format("\n\t@JsonSerialize(using = ToStringSerializer.class)\n\t@TableId(value = \"%s\", type = IdType.ASSIGN_ID)", c.getColumnName()));
            } else {
                //1、crt或者create开头的字段，设置@TableField(value = "crt_host", fill = FieldFill.INSERT)
                //2、upd开头,@TableField(value = "upd_time", fill = FieldFill.INSERT_UPDATE)
                String lowerCol = c.getColumnName().toLowerCase();
                if (lowerCol.startsWith("crt") || lowerCol.startsWith("create")) {
                    fieldInfo.append(String.format("\n\t@TableField(value = \"%s\", fill = FieldFill.INSERT)", c.getColumnName()));
                } else if (lowerCol.startsWith("upd")) {
                    fieldInfo.append(String.format("\n\t@TableField(value = \"%s\", fill = FieldFill.UPDATE)", c.getColumnName()));
                } else {
                    fieldInfo.append(String.format("\n\t@TableField(\"%s\")", c.getColumnName()));
                }
            }
            Type type = DbTypeToJavaTypeUtil.dbTypeToJavaType(c.getColumnType());
            //添加第三方导入类
            if (!thirdClzNameList.contains(type.getTypeName())) {
                thirdClzNameList.add(type.getTypeName());
            }
            fieldInfo.append(String.format("\n\tprivate %s %s;", PoJoUtil.getShortName(type.getTypeName()), PoJoUtil.lineToHump(c.getColumnName())));
        });
        return fieldInfo.toString();
    }


    /**
     * 添加域
     * @param columnInfoList    列信息
     * @param thirdClzNameList  第三方类集合
     * @date 2025/03/12 18:39
     **/
    public static String addField(List<ColumnInfo> columnInfoList, List<String> thirdClzNameList, String esFieldAno) {
        if (CollectionUtil.isEmpty(columnInfoList)) {
            return "";
        }
        StringBuilder fieldInfo = new StringBuilder();
        columnInfoList.forEach(c -> {
            fieldInfo.append(String.format("\n\n\t/**\n\t* %s\n\t*/", c.getColumnComment()));
            fieldInfo.append(String.format("\n\t@%s", PoJoUtil.getShortName(esFieldAno)));
            Type type = DbTypeToJavaTypeUtil.dbTypeToJavaType(c.getColumnType());
            //添加第三方导入类
            if (!thirdClzNameList.contains(type.getTypeName())) {
                thirdClzNameList.add(type.getTypeName());
            }
            fieldInfo.append(String.format("\n\tprivate %s %s;", PoJoUtil.getShortName(type.getTypeName()), PoJoUtil.lineToHump(c.getColumnName())));
        });
        return fieldInfo.toString();
    }


    /**
     * 添加序列化域
     * @date 2025/03/12 18:39
     **/
    public static String addSerialVersionUID() {
        return String.format("\n\t/**\n\t* serialVersionUID\n\t*/\n\tprivate static long serialVersionUID = %sL;", UuidUtil.generateNum(15));
    }


    /**
     * 添加auto域
     * @date 2025/03/12 18:39
     **/
    public static String addAutoField(String clzName) {
        return String.format("\n\t@Autowired\n\tprivate %s %s;", PoJoUtil.getShortName(clzName), PoJoUtil.firstToLower(PoJoUtil.getShortName(clzName)));
    }


    /**
     * 添加类注解
     * @param annotationList    注解列表
     * @date 2025/03/12 20:27
     **/
    public static String addClzAnnotation(List<AnnotationInfo> annotationList) {
        if (CollectionUtil.isEmpty(annotationList)) {
            return "";
        }
        StringBuilder annotations = new StringBuilder();
        annotationList.forEach(at -> {
            annotations.append(String.format("\n@%s", at.getName()));
            if (CollectionUtil.isEmpty(at.getFieldList())) {
                return;
            }
            String fieldStr = at.getFieldList().stream().map(v -> StringUtil.isEmpty(v.getValue()) ? String.format("\"%s\"", v.getName()) : String.format("%s = %s", v.getName(), Objects.equals(v.getHaveQuot(), true) ? String.format("\"%s\"", v.getValue()) : v.getValue())).collect(Collectors.joining(","));
            annotations.append(String.format("(%s)", fieldStr));
        });
        return annotations.toString();
    }


    /**
     * 是否有父类
     * @param elementSuper 元素父类,如：controller-enableSuper
     * @param tableSuper 表父类
     * @param elementSuperClass 元素父类
     * @date 2025/09/10 17:52
     **/
    public static boolean isHaveSuperClass(String elementSuper, String tableSuper, String elementSuperClass) {
        return "true".equals(elementSuper) && "true".equals(tableSuper) && StringUtil.isNotEmpty(elementSuperClass);
    }
}
